/*

Pinia

没有 Mutations

State
Getters
Actions   异步

1 安装
npm i pinia
2 使用
/store--index
import { createPinia } from 'pinia'

const pinia = createPinia()

export default pinia

main.js

// 引入pinia
import pinia from './pinia'

app.use( pinia )


/store/modules/mainStore.js 文件夹

import { defineStore } from 'pinia'

export const useMainStore = defineStore('main',{
  // 必须是 箭头函数  -- TS 类型推导
  state:()=>{
    return {
      count:100,
      foo:'bar',
      arr:[1,2,3]
    }
  }

  actions:{
    changeState(){
    //  this
     this.count ++
    // 批量 $patch
    this.$patch(state=>state.foo="hello")
    },
    changeState2(m){
    //  this
     this.count ++
    // 批量 $patch
    this.$patch(state=>state.foo="hello")
    }
  },

  getters:{
    count10(state){
      return state.count + 10
    },
    // TS  中  没有参数 state 无法推断返回值类型   需要手动 指定 :number
    count20(){
      return this.count + 20
    }
    // 调用 其他  getter
     count21(){
      return this.count20 + 20
    }
    // 接收参数 函数返回值 是一个函数  所以 组件中 调用 count22(100) 实际调用的是 箭头函数 m为100
     count22(state){
      return m =>state.count + m
    }
  }
})

定义store模式有2种：options API 和 composition API
上面 就是 options API  配置项

// 使用composition API模式定义store    setup  写法
export const useCounterStoreForSetup = defineStore('counterForSetup', () => {

  const count = ref<number>(1)

  const doubleCount = computed(() => count.value * 2)

  function increment() {
    count.value++
  }

  return { count, doubleCount, increment }

})

composition API中的ref、reactive定义的变量等价于options API中的state；
composition API中的computed属性等价于options API中的getters；
composition API中的导出函数等价于options API中的actions；


组件中

import { useMainStore } from '@/store'
// mainStore 为 reactive 对象
const mainStore = useMainStore()

const count = mainStore.count

// 解构  不是响应式的
const { count } = mainStore

// 解决方案 storeToRefs
import { storeToRefs } from 'pinia'

const { count } = storeToRefs(mainStore)
// count 为 ref 了  count.value

修改数据
1 直接修改
mainStore.count ++

2 批量修改  有性能优化 $patch 对象方式
mainStore.$patch({
  count:mainStore.count ++,
  foo:'hello',
  arr:[...mainStore.arr,4]
})

3 批量修改  有性能优化  $patch 函数方式
mainStore.$patch(state=>state.arr.push(4))

4 actions 中  处理逻辑
直接调用 actions 中方法
mainStore.changeState()

也可以 actions中定义 参数

mainStore.changeState2(10)

getters
mainStore.count10

重置数据
mainStore.$reset()

setup 插件 实现 $reset
const app = createApp(App);

const pinia = createPinia();
// use一个 函数  context 上下文 解构
pinia.use(({store})=>{

  const initialState = JSON.parse(JSON.stringify(store.$state));

  store.$reset = ()=>{
    // 对象 需要两次 转换
    store.$state = JSON.parse(JSON.stringify(initialState));

  }

});

直接替换  整个 state
mainStore.$state = { sex:'男'}

订阅  $patch  触发  无论值 是否改变
mainStore.$subscribe((mutation,state)=>{ mutation.payload })

只有 state 真正改变时才会触发
watch(mainStore.$state,()=>{})


持久化

npm i  pinia-plugin-persistedstate

/store/index

import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);

/store/modules/mainStore.js 文件夹

export const useStore = defineStore('main', {
  state: () => {
    return {
      someState: 'hello pinia',
      nested: {
        data: 'nested pinia',
      },
    }
  },
  // 所有数据持久化
  // persist: true,
  // 持久化存储插件其他配置
  persist: {
    // 修改存储中使用的键名称，默认为当前 Store的 id
    key: 'storeKey',
    // 修改为 sessionStorage，默认为 localStorage
    storage: window.sessionStorage,
    // 部分持久化状态的点符号路径数组，[]意味着没有状态被持久化(默认为undefined，持久化整个状态)
    paths: ['nested.data'],
  },
})

非组件  内  使用
要在使用处  const store = useStore()
而不是  函数外  定义

*/
